package com.example.teesystem.controller;

import com.example.teesystem.common.Permission.PermissionCheck;
import com.example.teesystem.common.cache.UserCache;
import com.example.teesystem.common.exception.CustomException;
import com.example.teesystem.common.utils.PermissionUtil;
import com.example.teesystem.common.utils.Response;
import com.example.teesystem.common.utils.ResultCode;
import com.example.teesystem.common.valid.MapContains;
import com.example.teesystem.common.valid.ValidErrorMessage;
import com.example.teesystem.entity.AdvancedTraining;
import com.example.teesystem.entity.AdvancedTrainingProgress;
import com.example.teesystem.entity.Issue;
import com.example.teesystem.entity.vo.advancedTrain.AdAnswer;
import com.example.teesystem.entity.vo.advancedTrain.AdvancedTrainUpdateVo;
import com.example.teesystem.entity.vo.advancedTrain.AdvancedTrainUploadVo;
import com.example.teesystem.entityDto.IssueSimpleMessage;
import com.example.teesystem.filter.MyHandlerInterceptor;
import com.example.teesystem.mapper.AdvancedTrainingProgressMapper;
import com.example.teesystem.mapper.IssueMapper;
import com.example.teesystem.service.AdvancedTrainingProgressService;
import com.example.teesystem.service.AdvancedTrainingService;
import com.example.teesystem.service.TrainIssueRelationService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/tee/advancedTraining", produces = "application/json; charset=utf-8")
@RequiredArgsConstructor
@Validated
public class AdvancedTrainingController {
    private final AdvancedTrainingService advancedTrainingService;
    private final IssueMapper issueMapper;
    private final TrainIssueRelationService trainIssueRelationService;
    private final AdvancedTrainingProgressMapper advancedTrainingProgressMapper;
    private final AdvancedTrainingProgressService advancedTrainingProgressService;
    
    /**
     * 添加进阶训练
     * @param advancedTrainUploadVo 添加信息
     * @return
     */
    @PermissionCheck(PermissionUtil.ADVANCED_TRAINING_MANAGE)
    @PostMapping("/add")
    public Response add(@Valid @RequestBody AdvancedTrainUploadVo advancedTrainUploadVo) {
        return advancedTrainingService.add(advancedTrainUploadVo);
    }
    
    /**
     * 更新题目
     * @param advancedTrainUpdateVo updateVo
     * @return
     */
    @PostMapping("/update")
    public Response update(@Valid @RequestBody AdvancedTrainUpdateVo advancedTrainUpdateVo) {
        if(!PermissionUtil.permissionCheck(MyHandlerInterceptor.getUid(), PermissionUtil.ADVANCED_TRAINING_MANAGE,advancedTrainingService.getCourseId(advancedTrainUpdateVo.getId()))) {
            return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
        }
        if(advancedTrainingService.update(advancedTrainUpdateVo)) {
            return Response.ok();
        } else {
            throw new CustomException(ResultCode.UPDATE_INFO_FAIL);
        }
    }
    
    /**
     * 删除题目
     * @param map 包含 ids
     * @return
     */
    @PostMapping("/deleteIssue")
    public Response delete(@RequestBody Map<String, List<Integer>> map) {
        List<Integer> ids = map.get("ids");
        if(ids == null || ids.isEmpty()) {
            throw new CustomException(ResultCode.PARAMETER_MISS);
        }
        if(advancedTrainingService.delete(ids)) {
            return Response.ok();
        } else {
            throw new CustomException(ResultCode.DELETE_INFO_FAIL);
        }
    }

    @PostMapping(value = "deleteAdvancedTraining")
    public Response deleteAdvancedTraining(@RequestBody Map<String,Integer> map){
        if(map.get("id") == null){
            return Response.error(ResultCode.PARAMETER_MISS);
        }
        Integer id = map.get("id");
        return advancedTrainingService.deleteAdvancedTraining(id);
    }
    
    /**
     * 获取进阶训练
     * @param map 包含 courseId
     * @return
     */
    @PostMapping("/get")
    public Response get(
            @MapContains(keys = {"courseId"}, message = ValidErrorMessage.COURSE_ID_VALID_FAIL)
            @RequestBody Map<String, Integer> map) {
        Integer courseId = map.get("courseId");
        return Response.ok(advancedTrainingService.get(courseId));
    }
    
    /**
     * 获取进阶训练
     * @param map 包含 id
     * @return
     */
    @PostMapping("/getIssues")
    public Response getIssues(
            @MapContains(keys = {"id"}, message = ValidErrorMessage.ADVANCED_TRAINING_ID_VALID_FAIL)
            @RequestBody Map<String, Integer> map) {
        Integer id = map.get("id");
        AdvancedTraining advancedTraining = advancedTrainingService.getById(id);
        if(UserCache.userMap.get(MyHandlerInterceptor.getUid()).getType() == 2 && advancedTraining.getPreAdvancedTraining() != 0 && advancedTraining.getIsOpen() != 1){
            AdvancedTrainingProgress advancedTrainProgress = advancedTrainingProgressMapper.getAdvancedTraining(advancedTraining.getPreAdvancedTraining(),MyHandlerInterceptor.getUid());
            if(advancedTrainProgress == null){
                return Response.error(ResultCode.ANSWER_PRE);
            }
        }
        List<Integer> issues = advancedTrainingService.getIssues(id);
        if(issues == null || issues.size()==0){
            List<IssueSimpleMessage> issueSimpleMessages = new ArrayList<>();
            return Response.ok(issueSimpleMessages);
        }
        List<Issue> issueList= issueMapper.getIssuesByIds(issues);
        List<IssueSimpleMessage> issueSimpleMessages = new ArrayList<>();
        for (Issue issue : issueList) {
            issueSimpleMessages.add(new IssueSimpleMessage(issue));
        }
        return Response.ok(issueSimpleMessages);
    }

    @PostMapping(value = "/answer")
    public Response answer(@RequestBody AdAnswer adAnswer){
        return advancedTrainingProgressService.answer(adAnswer);
    }
}
